/*
 *    Copyright 2021 FightingGuys Team
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package cn.fightingguys.kaiheila.event.source;

import cn.fightingguys.kaiheila.KhlKernel;
import cn.fightingguys.kaiheila.event.EventSource;
import cn.fightingguys.kaiheila.request.Route;
import okhttp3.*;
import okio.ByteString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * WebSocket 事件源
 *
 * @author running_hyk
 * @version 1.0.0
 * @since 1.0.0
 */
public class WebSocketEventSource extends EventSource {

    private static final Logger Log = LoggerFactory.getLogger(WebSocketEventSource.class);

    public WebSocketEventSource(KhlKernel khl) {
        super(khl);
        String u = null;
        do {
            u = DEBUG_getGateWayUrl();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ignored) {
            }
        } while (u == null);
        createWebSocketClient(u, khl.getHttpClient());
    }

    private void createWebSocketClient(String wssUrl, OkHttpClient client) {
        new WebSocketClient(wssUrl, super.khl.getHttpClient());
    }

    public class WebSocketClient extends WebSocketListener {

        private final OkHttpClient client;
        private final String wssUrl;
        private WebSocket socket;
        protected Thread senderThread;

        public WebSocketClient(String wssUrl, OkHttpClient client) {
            this.wssUrl = wssUrl;
            this.client = client;
            startWebSocketEvent();
        }

        private void startWebSocketEvent() {
            Request request = new Request.Builder().url(wssUrl).build();
            this.socket = client.newWebSocket(request, this);
            this.senderThread = new WebSocketSender();
        }

        public class WebSocketSender extends Thread {

            public WebSocketSender() {
                super("WebSocketSender");
                super.setDaemon(true);
            }

            @Override
            public void run() {
                while (!WebSocketEventSource.super.shutdown) {

                }
            }
        }

        @Override
        public void onOpen(WebSocket webSocket, Response response) {
            WebSocketEventSource.super.shutdown = true;
            senderThread.start();
        }

        @Override
        public void onMessage(WebSocket webSocket, ByteString bytes) {
            WebSocketEventSource.super.eventManager.handle(null);
        }

        @Override
        public void onClosing(WebSocket webSocket, int code, String reason) {

        }

        @Override
        public void onClosed(WebSocket webSocket, int code, String reason) {

        }

        @Override
        public void onFailure(WebSocket webSocket, Throwable t, Response response) {
            System.err.println(t.getMessage());
        }
    }

    private String DEBUG_getGateWayUrl() {
        OkHttpClient client = khl.getHttpClient();

        Request request = new Request.Builder()
                .url(Route.Misc.GATEWAY.compile().getFullRoute())
                .get()
                .build();
        String url = null;
        try {
            url = client.newCall(request).execute().body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return url;
    }

}
